﻿using Microsoft.EntityFrameworkCore;
using MiniErp.Entity.DataStreams;
using MiniErp.Entity.DataStreams.DOs.AssetManagement;
using MiniErp.Mysql.Data;
using MiniErp.Repository.MysqlRepository;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Text;
using System.Threading.Tasks;

namespace MiniErp.Repository.BaseRepository
{
    /// <summary>
    /// 仓储基类
    /// </summary>
    /// <typeparam name="TDBContext">泛型上下文（可能会使用多个数据库）</typeparam>
    /// <typeparam name="TEntity">泛型实体</typeparam>
    public class BaseRepository<TDBContext, TEntity> : IBaseRepository<TEntity>
        where TDBContext : DbContext
        where TEntity : BaseEntity
    {

        public readonly DbSet<TEntity> _set;
        public readonly TDBContext _dbContext;
        public BaseRepository(TDBContext dbContext)
        {
            _dbContext = dbContext;
            _set = _dbContext.Set<TEntity>();
        }
        public void AddInfoAsync(TEntity t)
        {
            _set.Add(t);
        }
        public void AddInfoAsync(List<TEntity> t)
        {
            t.ForEach(item =>
            {
                _set.Add(item);
            });
        }
        public void DeleteInfoAsync(TEntity t)
        {
            _set.Remove(t);
        }
        public void DeleteInfoAsync(List<TEntity> t)
        {
            t.ForEach(item =>
            {
                _set.Remove(item);
            });
        }
        public void UpdateInfoAsync(TEntity t)
        {
            _set.Update(t);
        }

        public void UpdateInfoAsync(List<TEntity> t)
        {
            t.ForEach(item =>
            {
                _set.Update(item);
            });
        }

        public async Task<TEntity> GetInfoAsync(Expression<Func<TEntity, bool>> lambda)
        {
            return await _set.SingleOrDefaultAsync(lambda);
        }
        public async Task<List<TEntity>> GetInfoAsyncs<Ttype>(Expression<Func<TEntity, bool>> lambda, int Page, int num, string value, bool isAsc = true)
        {
            return isAsc
             ? await _set
              .Where(lambda)
              .OrderBy(item => EF.Property<Ttype>(item, value))
              .Skip((Page - 1) * num)
              .Take(num)
              .ToListAsync()
             : await _set
              .Where(lambda)
              .OrderByDescending(item => EF.Property<Ttype>(item, value))
              .Skip((Page - 1) * num)
              .Take(num)
              .ToListAsync();
        }
        public async Task<List<TEntity>> GetInfoAsyncs(Expression<Func<TEntity, bool>> lambda)
        {
            return await _set.Where(lambda).ToListAsync();
        }


        public async Task<List<TEntity>> GetInfoAsyncs<Ttype>(int Page, int num, string value, bool isAsc = true)
        {
            return isAsc
            ? await _set
             .OrderBy(item => EF.Property<Ttype>(item, value))
             .Skip((Page - 1) * num)
             .Take(num)
             .ToListAsync()
            : await _set
             .OrderByDescending(item => EF.Property<Ttype>(item, value))
             .Skip((Page - 1) * num)
             .Take(num)
             .ToListAsync();
        }
        public async Task<List<TEntity>> GetInfoAsyncs()
        {
            return await _set.ToListAsync();
        }

        public async Task<int> GetInfoNumsAsync(Expression<Func<TEntity, bool>> lambda)
        {
            return await _set.CountAsync(lambda);
        }


    }
}
